package com.ciaojian.client.service;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ciaojian.core.mapper.AdvertisementMapper;
import com.ciaojian.core.mapper.UserMapper;
import com.ciaojian.core.mapper.UserStoreMapper;
import com.ciaojian.core.model.Advertisement;
import com.ciaojian.core.model.UserStore;
import com.ciaojian.core.service.AdvertisementService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author Atlakyn
 */
@Service
public class AdvertisementServiceImpl extends ServiceImpl<AdvertisementMapper, Advertisement> implements AdvertisementService {
    @Resource
    private UserMapper userMapper;
    @Resource
    private UserStoreMapper userStoreMapper;

    /**
     * 获取弹窗信息
     * <p>根据广告的投放用户标签和投放门店进行筛选</p>
     * <p>用户必须是这个标签人群且在投放门店中有过消费才可看到广告</p>
     *
     * @param userId 用户
     * @return 广告列表
     */
    public Set<Advertisement> popSet(Integer userId) {
        // 获取用户标签,拆成数组
        String label = userMapper.getLabelsById(userId);

        String[] labels = StrUtil.isEmpty(label) ? new String[]{} : label.split(",");

        // 获取有效且在活动期内的广告
        QueryWrapper<Advertisement> queryWrapper = new QueryWrapper<>();
        Date date = new Date();
        queryWrapper.eq("status", 1)
                .le("start_time", date)
                .ge("end_time", date)
                .orderByAsc("sort")
        ;
        // 全部弹窗广告集合
        List<Advertisement> advertisementList = this.baseMapper.selectList(queryWrapper);
        // 过滤后的弹窗广告集合,不允许有重复元素
        Set<Advertisement> effActivityPopList = new HashSet<>();

        // 获取用户消费过的门店列表
        QueryWrapper<UserStore> queryUserStore = new QueryWrapper<>();
        queryUserStore.eq("user_id", userId);
        List<UserStore> userStoreList = userStoreMapper.selectList(queryUserStore);

        // 根据用户标签遍历广告
        advertisementList.forEach(advertisement -> {
            String[] storeId = advertisement.getStoreId().split(",");
            for (String l : labels) {
                // 判断用户的标签是否符合广告标签群
                // 判断用户所消费的门店
                if (checkLabelContains(l, advertisement.getLabel())) {
                    if ("0".equals(advertisement.getStoreId())) {
                        effActivityPopList.add(advertisement);
                    } else {
                        userStoreList.forEach(userStore -> {
                            for (int j = 0, size = storeId.length; j < size; j++) {
                                if (checkStoreContains(advertisement.getStoreId(), userStore.getStoreId())) {
                                    effActivityPopList.add(advertisement);
                                }
                            }
                        });
                    }
                }
            }
        });
        // 按排序字段排序
        Set<Advertisement> sortSet = new TreeSet<>(Comparator.comparing(Advertisement::getSort));
        sortSet.addAll(effActivityPopList);
        return sortSet;
    }

    /**
     * 检查用户标签是否包含
     *
     * @param label        投放标签
     * @param labelStrList 用户标签
     * @return 包含返回 true
     */
    private Boolean checkLabelContains(String label, String labelStrList) {
        Integer integer = baseMapper.checkLabelContains(label, labelStrList);
        // 大于 0 表示包含
        return integer > 0;
    }

    /**
     * 检查用户是否在投放门店消费过
     *
     * @param storeId     投放门店
     * @param userStoreId 用户消费门店
     * @return 包含返回 true
     */
    private Boolean checkStoreContains(String storeId, Integer userStoreId) {
        Integer integer = baseMapper.checkStoreContains(storeId, userStoreId);
        // 大于 0 表示包含
        return integer > 0;
    }
}

